/* Process IKEv2 IKE_SA_INIT packets, for libreswan
 *
 * Copyright (C) 1997 Angelos D. Keromytis.
 * Copyright (C) 1998-2010,2013-2017 D. Hugh Redelmeier <hugh@mimosa.com>
 * Copyright (C) 2007-2008 Michael Richardson <mcr@xelerance.com>
 * Copyright (C) 2009 David McCullough <david_mccullough@securecomputing.com>
 * Copyright (C) 2008-2011 Paul Wouters <paul@xelerance.com>
 * Copyright (C) 2010 Simon Deziel <simon@xelerance.com>
 * Copyright (C) 2010 Tuomo Soini <tis@foobar.fi>
 * Copyright (C) 2011-2012 Avesh Agarwal <avagarwa@redhat.com>
 * Copyright (C) 2012 Paul Wouters <paul@libreswan.org>
 * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com>
 * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com>
 * Copyright (C) 2015-2019 Andrew Cagney
 * Copyright (C) 2016-2018 Antony Antony <appu@phenome.org>
 * Copyright (C) 2017 Sahana Prasad <sahana.prasad07@gmail.com>
 * Copyright (C) 2020 Yulia Kuzovkova <ukuzovkova@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <https://www.gnu.org/licenses/gpl2.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include "defs.h"
#include "demux.h"
#include "log.h"
#include "state.h"
#include "ikev2_send.h"
#include "ikev2_redirect.h"
#include "ikev2_host_pair.h"
#include "ikev2_states.h"
#include "vendor.h"
#include "ikev2_cookie.h"
#include "ikev2.h"
#include "ikev2_ike_sa_init.h"
#include "ikev2_ike_intermediate.h"
#include "ikev2_ike_auth.h"
#include "connections.h"
#include "crypt_ke.h"
#include "nat_traversal.h"
#include "ikev2_nat.h"
#include "unpack.h"
#include "ikev2_message.h"
#include "crypt_dh.h"
#include "ipsec_doi.h"			/* for has_preloaded_public_key()!?! */
#include "ikev2_send.h"
#include "pluto_x509.h"
#include "iface.h"
#include "pending.h"
#include "ikev2_ipseckey.h"
#include "pluto_stats.h"

void process_v2_IKE_SA_INIT(struct msg_digest *md)
{
	/*
	 * The message ID of the initial exchange is always
	 * zero.
	 */
	if (md->hdr.isa_msgid != 0) {
		rate_log(md, "IKE_SA_INIT message has non-zero message ID; dropping packet");
		return;
	}
	/*
	 * Now try to find the state
	 */
	switch (v2_msg_role(md)) {

	case MESSAGE_REQUEST:
	{

		/*
		 * 3.1.  The IKE Header (Flags)
		 *
		 * * I (Initiator) - This bit MUST be set in messages
		 *   sent by the original initiator of the IKE SA and
		 *   MUST be cleared in messages sent by the original
		 *   responder.  It is used by the recipient to
		 *   determine which eight octets of the SPI were
		 *   generated by the recipient.  This bit changes to
		 *   reflect who initiated the last rekey of the IKE
		 *   SA.
		 *
		 * i.e., in the request, I must be set
		 */
		if (!(md->hdr.isa_flags & ISAKMP_FLAGS_v2_IKE_I)) {
			rate_log(md, "IKE_SA_INIT request has I (IKE Initiator) flag clear; dropping packet");
			return;
		}

		/*
		 * 3.1.  The IKE Header (IKE SA Initiator SPI)
		 *
		 * o Initiator's SPI (8 octets) - A value chosen by
		 *   the initiator to identify a unique IKE Security
		 *   Association.  This value MUST NOT be zero.
		 *
		 * (it isn't obvious why this rule is needed;
		 * exchanges still work)
		 */
		if (ike_spi_is_zero(&md->hdr.isa_ike_initiator_spi)) {
			rate_log(md, "IKE_SA_INIT request has zero IKE SA Initiator SPI; dropping packet");
			return;
		}

		/*
		 * 3.1.  The IKE Header (IKE SA Responder SPI)
		 *
		 * o Responder's SPI (8 octets) - A value chosen by
		 *   the responder to identify a unique IKE Security
		 *   Association.  This value MUST be zero in the
		 *   first message of an IKE initial exchange
		 *   (including repeats of that message including a
		 *   cookie).
		 *
		 * (since this is the very first message, the
		 * initiator can't know the responder's SPI).
		 */
		if (!ike_spi_is_zero(&md->hdr.isa_ike_responder_spi)) {
			rate_log(md, "IKE_SA_INIT request has non-zero IKE SA Responder SPI; dropping packet");
			return;
		}

		/*
		 * Look for a pre-existing IKE SA responder state
		 * using just the SPIi (SPIr in the message is zero so
		 * can't be used).
		 *
		 * XXX: RFC 7296 says this isn't sufficient:
		 *
		 *   2.1.  Use of Retransmission Timers
		 *
		 *   Retransmissions of the IKE_SA_INIT request
		 *   require some special handling.  When a responder
		 *   receives an IKE_SA_INIT request, it has to
		 *   determine whether the packet is a retransmission
		 *   belonging to an existing "half-open" IKE SA (in
		 *   which case the responder retransmits the same
		 *   response), or a new request (in which case the
		 *   responder creates a new IKE SA and sends a fresh
		 *   response), or it belongs to an existing IKE SA
		 *   where the IKE_AUTH request has been already
		 *   received (in which case the responder ignores
		 *   it).
		 *
		 *   It is not sufficient to use the initiator's SPI
		 *   and/or IP address to differentiate between these
		 *   three cases because two different peers behind a
		 *   single NAT could choose the same initiator SPI.
		 *   Instead, a robust responder will do the IKE SA
		 *   lookup using the whole packet, its hash, or the
		 *   Ni payload.
		 *
		 * But realistically, either there's an IOT device
		 * sending out a hardwired SPIi, or there is a clash
		 * and a retry will generate a new conflicting SPIi.
		 *
		 * If the lookup succeeds then there are several
		 * possibilities:
		 *
		 * State has Message ID == 0:
		 *
		 * Either it really is a duplicate; or it's a second
		 * (fake?) intiator sending the same SPIi at exactly
		 * the same time as the first (wow, what are the odds,
		 * it must be our lucky day!).
		 *
		 * Either way, the duplicate code needs to compare
		 * packets and decide if a retransmit or drop is
		 * required.  If the second initiator is real, then it
		 * will timeout and then retry with a new SPIi.
		 *
		 * State has Message ID > 0:
		 *
		 * Either it is an old duplicate; or, again, it's a
		 * second intiator sending the same SPIi only slightly
		 * later (again, what are the odds!).
		 *
		 * Several choices: let the duplicate code drop the
		 * packet, which is correct for an old duplicate
		 * message; or ignore the existing state and create a
		 * new one, which is good for the second initiator but
		 * not so good for an old duplicate.  Given an old
		 * duplicate is far more likely, handle that cleenly -
		 * let the duplicate code drop the packet.
		 */
		struct ike_sa *old = find_v2_ike_sa_by_initiator_spi(&md->hdr.isa_ike_initiator_spi,
								     SA_RESPONDER);
		if (old != NULL) {
			intmax_t msgid = md->hdr.isa_msgid;
			pexpect(msgid == 0); /* per above */
			/* XXX: keep test results happy */
			if (md->fake_clone) {
				log_state(RC_LOG, &old->sa, "IMPAIR: processing a fake (cloned) message");
			}
			if (verbose_state_busy(&old->sa)) {
				/* already logged */;
			} else if (old->sa.st_state->kind == STATE_PARENT_R1 &&
				   old->sa.st_v2_msgid_windows.responder.recv == 0 &&
				   old->sa.st_v2_msgid_windows.responder.sent == 0 &&
				   hunk_eq(old->sa.st_firstpacket_peer,
					   same_pbs_in_as_shunk(&md->message_pbs))) {
				/*
				 * It looks a lot like a shiny new IKE
				 * SA that only just responded to a
				 * message identical to this one.
				 * Re-transmit the response.
				 *
				 * XXX: Log message matches
				 * is_duplicate_request() - keep test
				 * results happy.
				 */
				log_state(RC_LOG, &old->sa,
					  "received duplicate %s message request (Message ID %jd); retransmitting response",
					  enum_name_short(&ikev2_exchange_names, md->hdr.isa_xchg),
					  msgid);
				send_recorded_v2_message(old, "IKE_SA_INIT responder retransmit",
							 MESSAGE_RESPONSE);
			} else {
				/*
				 * Either:
				 *
				 * - it is an old duplicate and the
				 *   packet should be dropped
				 *
				 * - it's a second intiator using the
				 *   same SPIi (wow!) and a new IKE SA
				 *   should be created
				 *
				 * However the odds of the later are
				 * essentially zero so assume the
				 * former and drop the packet.
				 *
				 * XXX: Log message matches
				 * is_duplicate_request() - keep test
				 * results happy.
				 */
				log_state(RC_LOG, &old->sa,
					  "received too old retransmit: %jd < %jd",
					  msgid, old->sa.st_v2_msgid_windows.responder.sent);
			}
			return;
		}

		if (drop_new_exchanges()) {
			/* only log for debug to prevent disk filling up */
			dbg("pluto is overloaded with half-open IKE SAs; dropping new exchange");
			return;
		}

		/*
		 * Always check for cookies!
		 *
		 * XXX: why?
		 *
		 * Because the v2N_COOKIE payload is first, parsing
		 * and verifying it should be relatively quick and
		 * cheap.  Right?
		 *
		 * No.  The equation uses v2Ni forcing the entire
		 * payload to be parsed.
		 *
		 * The error notification is probably INVALID_SYNTAX,
		 * but could be v2N_UNSUPPORTED_CRITICAL_PAYLOAD.
		 */
		pexpect(!md->message_payloads.parsed);
		md->message_payloads = ikev2_decode_payloads(md->md_logger, md,
							     &md->message_pbs,
							     md->hdr.isa_np);
		if (md->message_payloads.n != v2N_NOTHING_WRONG) {
			if (require_ddos_cookies()) {
				dbg("DDOS so not responding to invalid packet");
			} else {
				shunk_t data = shunk2(md->message_payloads.data,
						      md->message_payloads.data_size);
				send_v2N_response_from_md(md, md->message_payloads.n,
							  &data);
			}
			return;
		}

		/*
		 * Do I want a cookie?
		 */
		if (v2_rejected_initiator_cookie(md, require_ddos_cookies())) {
			dbg("pluto is overloaded and demanding cookies; dropping new exchange");
			return;
		}

		/*
		 * Check for v2N_REDIRECT_SUPPORTED /
		 * v2N_REDIRECTED_FROM notification.  If redirection
		 * is a MUST, try to respond with v2N_REDIRECT and
		 * don't continue further.  Otherwise continue as
		 * usual.
		 *
		 * The function below will do everything (and log the
		 * result).
		 */
		if (redirect_global(md)) {
			return;
		}

		/*
		 * Check if we would drop the packet based on VID
		 * before we create a state. Move this to
		 * ikev2_oppo.c: drop_oppo_requests()?
		 */
		for (struct payload_digest *p = md->chain[ISAKMP_NEXT_v2V]; p != NULL; p = p->next) {
			if (vid_is_oppo((char *)p->pbs.cur, pbs_left(&p->pbs))) {
				if (pluto_drop_oppo_null) {
					dbg("Dropped IKE request for Opportunistic IPsec by global policy");
					return;
				}
				dbg("Processing IKE request for Opportunistic IPsec");
				break;
			}
		}

		/*
		 * Does the message match the (only) expected
		 * transition?
		 */
		const struct finite_state *start_state = finite_states[STATE_PARENT_R0];
		const struct v2_state_transition *transition =
			find_v2_state_transition(md->md_logger, start_state, md);
		if (transition == NULL) {
			/* already logged */
			send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL);
			return;
		}

		/*
		 * Is there a connection that matches the message?
		 */
		lset_t policy = LEMPTY;
		bool send_reject_response = true;
		struct connection *c = find_v2_host_pair_connection(md, &policy,
								    &send_reject_response);
		if (c == NULL) {
			if (send_reject_response) {
				/*
				 * NO_PROPOSAL_CHOSEN is used when the
				 * list of proposals is empty, like
				 * when we did not find any connection
				 * to use.
				 *
				 * INVALID_SYNTAX is for errors that a
				 * configuration change could not fix.
				 */
				send_v2N_response_from_md(md, v2N_NO_PROPOSAL_CHOSEN, NULL);
			}
			return;
		}

		/*
		 * We've committed to creating a state and,
		 * presumably, dedicating real resources to the
		 * connection.
		 */
		struct ike_sa *ike = new_v2_ike_state(c, transition, SA_RESPONDER,
						      md->hdr.isa_ike_spis.initiator,
						      ike_responder_spi(&md->sender,
									md->md_logger),
						      policy, 0, null_fd);

		statetime_t start = statetime_backdate(&ike->sa, &md->md_inception);
		/* XXX: keep test results happy */
		if (md->fake_clone) {
			log_state(RC_LOG, &ike->sa, "IMPAIR: processing a fake (cloned) message");
		}
		v2_dispatch(ike, &ike->sa, md, transition);
		statetime_stop(&start, "%s()", __func__);
		return;
	}

	case MESSAGE_RESPONSE:
	{
		/*
		 * 3.1.  The IKE Header (Flags)
		 *
		 * * I (Initiator) - This bit MUST be set in messages
		 *   sent by the original initiator of the IKE SA and
		 *   MUST be cleared in messages sent by the original
		 *   responder.  It is used by the recipient to
		 *   determine which eight octets of the SPI were
		 *   generated by the recipient.  This bit changes to
		 *   reflect who initiated the last rekey of the IKE
		 *   SA.
		 *
		 * i.e., in the response I must be clear
		 */
		if (md->hdr.isa_flags & ISAKMP_FLAGS_v2_IKE_I) {
			rate_log(md, "IKE_SA_INIT response has I (IKE Initiator) flag set; dropping packet");
			return;
		}

		/*
		 * 2.6.  IKE SA SPIs and Cookies:
		 *
		 *   When the IKE_SA_INIT exchange does not result in
		 *   the creation of an IKE SA due to
		 *   INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN, or
		 *   COOKIE, the responder's SPI will be zero also in
		 *   the response message.  However, if the responder
		 *   sends a non-zero responder SPI, the initiator
		 *   should not reject the response for only that
		 *   reason.
		 *
		 * i.e., can't check response for non-zero SPIr.
		 *
		 * Look for a pre-existing IKE SA responder state
		 * using just the SPIi (SPIr in the message isn't
		 * known so can't be used).
		 *
		 * An IKE_SA_INIT error notification response
		 * (INVALID_KE, COOKIE) should contain a zero SPIr (it
		 * must be ignored).
		 *
		 * An IKE_SA_INIT success response will contain an as
		 * yet unknown but non-zero SPIr so looking for it
		 * won't work.
		 */
		struct ike_sa *ike = find_v2_ike_sa_by_initiator_spi(&md->hdr.isa_ike_initiator_spi,
								     SA_INITIATOR);
		if (ike == NULL) {
			/*
			 * There should be a state matching the
			 * original initiator's IKE SPIs.  Since there
			 * isn't someone's playing games.  Drop the
			 * packet.
			 */
			rate_log(md, "dropping IKE_SA_INIT response no matching IKE ISA");
			return;
		}

		if (ike->sa.st_state->kind != STATE_PARENT_I1 ||
		    ike->sa.st_v2_msgid_windows.initiator.sent != 0 ||
		    ike->sa.st_v2_msgid_windows.initiator.recv != -1 ||
		    ike->sa.st_v2_msgid_wip.initiator != 0) {
			/*
			 * This doesn't seem right; drop the
			 * packet.
			 */
			rate_log(md, "dropping IKE_SA_INIT response as unexpected for matching IKE SA #%lu",
				 ike->sa.st_serialno);
			return;
		}

		if (verbose_state_busy(&ike->sa)) {
			return;
		}

		dbg("unpacking clear payloads");
		md->message_payloads = ikev2_decode_payloads(ike->sa.st_logger, md,
							     &md->message_pbs,
							     md->hdr.isa_np);
		if (md->message_payloads.n != v2N_NOTHING_WRONG) {
			/* already logged */
			return;
		}

		/* transition? */
		const struct v2_state_transition *transition =
			find_v2_state_transition(ike->sa.st_logger, ike->sa.st_state, md);
		if (transition == NULL) {
			/* already logged */
			return;
		}

		statetime_t start = statetime_backdate(&ike->sa, &md->md_inception);
		v2_dispatch(ike, &ike->sa, md, transition);
		statetime_stop(&start, "%s()", __func__);
		return;
	}

	default:
		bad_case(v2_msg_role(md));
	}

}


/*
 *
 ***************************************************************
 *****                   PARENT_OUTI1                      *****
 ***************************************************************
 *
 *
 * Initiate an Oakley Main Mode exchange.
 *       HDR, SAi1, KEi, Ni   -->
 *
 * Note: this is not called from demux.c, but from ipsecdoi_initiate().
 *
 */
static ke_and_nonce_cb ikev2_parent_outI1_continue;

void ikev2_out_IKE_SA_INIT_I(struct connection *c,
			     struct state *predecessor,
			     lset_t policy,
			     unsigned long try,
			     const threadtime_t *inception,
			     shunk_t sec_label,
			     bool background, struct logger *logger)
{
	if (drop_new_exchanges()) {
		/* Only drop outgoing opportunistic connections */
		if (c->policy & POLICY_OPPORTUNISTIC) {
			return;
		}
	}

	const struct finite_state *fs = finite_states[STATE_PARENT_I0];
	pexpect(fs->nr_transitions == 1);
	const struct v2_state_transition *transition = &fs->v2_transitions[0];
	struct ike_sa *ike = new_v2_ike_state(c, transition, SA_INITIATOR,
					      ike_initiator_spi(), zero_ike_spi,
					      policy, try, logger->global_whackfd);
	statetime_t start = statetime_backdate(&ike->sa, inception);

	/* set up new state */
	passert(ike->sa.st_ike_version == IKEv2);
	passert(ike->sa.st_state->kind == STATE_PARENT_I0);
	passert(ike->sa.st_sa_role == SA_INITIATOR);
	ike->sa.st_try = try;

	if ((c->iketcp == IKE_TCP_ONLY) || (try > 1 && c->iketcp != IKE_TCP_NO)) {
		dbg("TCP: forcing #%lu remote endpoint port to %d",
		    ike->sa.st_serialno, c->remote_tcpport);
		update_endpoint_port(&ike->sa.st_remote_endpoint, ip_hport(c->remote_tcpport));
		struct iface_endpoint *ret = create_tcp_interface(ike->sa.st_interface->ip_dev,
								  ike->sa.st_remote_endpoint,
								  ike->sa.st_logger);
		if (ret == NULL) {
			/* TCP: already logged? */
			delete_state(&ike->sa);
			return;
		}
		/*
		 * TCP: leaks old st_interface?
		 *
		 * XXX: perhaps; first time through .st_interface
		 * points at the packet interface (ex UDP) which is
		 * shared between states; but once that is replaced by
		 * a per-state interface it could well leak?
		 *
		 * Fix by always refcnting struct iface_endpoint?
		 */
		ike->sa.st_interface = ret;
	}

	if (c->spd.this.sec_label.len > 0 && sec_label.len == 0) {
		/*
		 * Establishing a sec-label connection yet there's no
		 * sec-label.  Assume this is a forced up.
		 */
		pexpect(c->kind == CK_TEMPLATE);
		dbg("template connection sec_label="PRI_SHUNK" but initiate does not; skipping child",
		    pri_shunk(c->spd.this.sec_label));
	} else if (HAS_IPSEC_POLICY(policy) &&
		   c->spd.this.sec_label.len > 0 && sec_label.len > 0 &&
		   c->kind == CK_TEMPLATE) {
		/* Toss the acquire onto the pending queue */
		ip_address remote_address = endpoint_address(ike->sa.st_remote_endpoint);
		struct connection *d = instantiate(c, &remote_address, NULL);
		/* replace connection template label with ACQUIREd label */
		free_chunk_content(&d->spd.this.sec_label);
		d->spd.this.sec_label = clone_hunk(sec_label, "ACQUIRED sec_label");
		free_chunk_content(&d->spd.that.sec_label);
		d->spd.that.sec_label = clone_hunk(sec_label, "ACQUIRED sec_label");
		add_pending(background ? null_fd : ike->sa.st_logger->global_whackfd, ike, d, policy, 1,
			    /*predecessor*/SOS_NOBODY,
			    sec_label, true /*part of initiate*/);
		connection_buf db;
		dbg("generating and then tossing child connection "PRI_CONNECTION" with sec_label="PRI_SHUNK" into the pending queue",
		    pri_connection(d, &db), pri_shunk(sec_label));
	} else if (impair.omit_v2_ike_auth_child) {
		llog_sa(RC_LOG, ike, "IMPAIR: omitting CHILD SA payloads from the IKE_AUTH request");
	} else if (HAS_IPSEC_POLICY(policy)) {
		add_pending(background ? null_fd : logger->global_whackfd, ike, c, policy, 1,
			    predecessor == NULL ? SOS_NOBODY : predecessor->st_serialno,
			    sec_label, true /*part of initiate*/);
	}

	/*
	 * XXX: why limit this log line to whack when opportunistic?
	 * This was, after all, triggered by something that happened
	 * at this end.
	 */
	enum stream log_stream = ((c->policy & POLICY_OPPORTUNISTIC) == LEMPTY) ? ALL_STREAMS : WHACK_STREAM;

	if (predecessor != NULL) {
		const char *what;
		if (IS_CHILD_SA_ESTABLISHED(predecessor)) {
			ike->sa.st_ipsec_pred = predecessor->st_serialno;
			what = "established CHILD SA";
		} else if (IS_IKE_SA_ESTABLISHED(predecessor)) {
			ike->sa.st_ike_pred = predecessor->st_serialno;
			what = "established IKE SA";
		} else if (IS_IKE_SA(predecessor)) {
			what = "establishing IKE SA";
		} else {
			what = "establishing CHILD SA";
		}
		log_state(log_stream | (RC_NEW_V2_STATE + STATE_PARENT_I1), &ike->sa,
			  "initiating IKEv2 connection to replace %s #%lu",
			  what, predecessor->st_serialno);
		update_pending(ike_sa(predecessor, HERE), ike);
	} else {
		log_state(log_stream | (RC_NEW_V2_STATE + STATE_PARENT_I1), &ike->sa,
			  "initiating IKEv2 connection");
	}

	/*
	 * XXX: hack: detach from whack _after_ the above message has
	 * been logged.  Better to do that in the caller?
	 */
	if (background) {
		close_any(&ike->sa.st_logger->object_whackfd);
		close_any(&ike->sa.st_logger->global_whackfd);
	}

	if (IS_LIBUNBOUND && id_ipseckey_allowed(ike, IKEv2_AUTH_RESERVED)) {
		stf_status ret = idr_ipseckey_fetch(ike);
		if (ret != STF_OK) {
			return;
		}
	}

	/*
	 * Initialize ike->sa.st_oakley, including the group number.
	 * Grab the DH group from the first configured proposal and build KE.
	 */
	struct ikev2_proposals *ike_proposals =
		get_v2_ike_proposals(c, "IKE SA initiator selecting KE", ike->sa.st_logger);
	ike->sa.st_oakley.ta_dh = ikev2_proposals_first_dh(ike_proposals, ike->sa.st_logger);
	if (ike->sa.st_oakley.ta_dh == NULL) {
		log_state(RC_LOG, &ike->sa, "proposals do not contain a valid DH");
		delete_state(&ike->sa);
		return;
	}

	/*
	 * Calculate KE and Nonce.
	 */
	submit_ke_and_nonce(&ike->sa, ike->sa.st_oakley.ta_dh,
			    ikev2_parent_outI1_continue,
			    "ikev2_outI1 KE");
	statetime_stop(&start, "%s()", __func__);
}

stf_status ikev2_parent_outI1_continue(struct state *ike_st,
				       struct msg_digest *unused_md,
				       struct dh_local_secret *local_secret,
				       chunk_t *nonce)
{
	struct ike_sa *ike = pexpect_ike_sa(ike_st);
	pexpect(ike->sa.st_sa_role == SA_INITIATOR);
	pexpect(unused_md == NULL);
	/* I1 is from INVALID KE */
	pexpect(ike->sa.st_state->kind == STATE_PARENT_I0 ||
		ike->sa.st_state->kind == STATE_PARENT_I1);
	dbg("%s() for #%lu %s",
	     __func__, ike->sa.st_serialno, ike->sa.st_state->name);

	unpack_KE_from_helper(&ike->sa, local_secret, &ike->sa.st_gi);
	unpack_nonce(&ike->sa.st_ni, nonce);
	return record_v2_IKE_SA_INIT_request(ike) ? STF_OK : STF_INTERNAL_ERROR;
}

bool record_v2_IKE_SA_INIT_request(struct ike_sa *ike)
{
	struct connection *c = ike->sa.st_connection;

	/* set up reply */
	struct pbs_out reply_stream = open_pbs_out("reply packet",
						   reply_buffer, sizeof(reply_buffer),
						   ike->sa.st_logger);

	if (impair.send_bogus_dcookie) {
		/* add or mangle a dcookie so what we will send is bogus */
		DBG_log("Mangling dcookie because --impair-send-bogus-dcookie is set");
		replace_chunk(&ike->sa.st_dcookie, alloc_chunk(1, "mangled dcookie"));
		messupn(ike->sa.st_dcookie.ptr, 1);
	}

	/* HDR out */

	pb_stream rbody = open_v2_message(&reply_stream, ike, NULL /* request */,
					  ISAKMP_v2_IKE_SA_INIT);
	if (!pbs_ok(&rbody)) {
		return false;
	}

	/*
	 * https://tools.ietf.org/html/rfc5996#section-2.6
	 * reply with the anti DDOS cookie if we received one (remote is under attack)
	 */
	if (ike->sa.st_dcookie.ptr != NULL) {
		/* In v2, for parent, protoid must be 0 and SPI must be empty */
		if (!emit_v2N_hunk(v2N_COOKIE, ike->sa.st_dcookie, &rbody)) {
			return false;
		}
	}

	/* SA out */

	struct ikev2_proposals *ike_proposals =
		get_v2_ike_proposals(c, "IKE SA initiator emitting local proposals", ike->sa.st_logger);
	if (!ikev2_emit_sa_proposals(&rbody, ike_proposals,
				     (chunk_t*)NULL /* IKE - no CHILD SPI */)) {
		return false;
	}

	/*
	 * ??? from here on, this looks a lot like the end of
	 * ikev2_in_IKE_SA_INIT_I_out_IKE_SA_INIT_R_tail.
	 */

	/* send KE */
	if (!emit_v2KE(&ike->sa.st_gi, ike->sa.st_oakley.ta_dh, &rbody))
		return false;

	/* send NONCE */
	{
		pb_stream pb;
		struct ikev2_generic in = {
			.isag_critical = build_ikev2_critical(false, ike->sa.st_logger),
		};

		if (!out_struct(&in, &ikev2_nonce_desc, &rbody, &pb) ||
		    !out_hunk(ike->sa.st_ni, &pb, "IKEv2 nonce"))
			return false;

		close_output_pbs(&pb);
	}

	/* Send fragmentation support notification */
	if (c->policy & POLICY_IKE_FRAG_ALLOW) {
		if (!emit_v2N(v2N_IKEV2_FRAGMENTATION_SUPPORTED, &rbody))
			return false;
	}

	/* Send USE_PPK Notify payload */
	if (LIN(POLICY_PPK_ALLOW, c->policy)) {
		if (!emit_v2N(v2N_USE_PPK, &rbody))
			return false;
	}

	/* Send INTERMEDIATE_EXCHANGE_SUPPORTED Notify payload */
	if (c->policy & POLICY_INTERMEDIATE) {
		if (!emit_v2N(v2N_INTERMEDIATE_EXCHANGE_SUPPORTED, &rbody))
			return STF_INTERNAL_ERROR;
	}

	/* first check if this IKE_SA_INIT came from redirect
	 * instruction.
	 * - if yes, send the v2N_REDIRECTED_FROM
	 *   with the identity of previous gateway
	 * - if not, check if we support redirect mechanism
	 *   and send v2N_REDIRECT_SUPPORTED if we do
	 */
	if (address_is_specified(c->temp_vars.redirect_ip)) {
		if (!emit_redirected_from_notification(&c->temp_vars.old_gw_address, &rbody))
			return false;
	} else if (LIN(POLICY_ACCEPT_REDIRECT_YES, c->policy)) {
		if (!emit_v2N(v2N_REDIRECT_SUPPORTED, &rbody))
			return false;
	}

	/* Send SIGNATURE_HASH_ALGORITHMS Notify payload */
	if (!impair.omit_hash_notify_request) {
		if (((c->policy & POLICY_RSASIG) || (c->policy & POLICY_ECDSA))
			&& (c->sighash_policy != LEMPTY)) {
			if (!emit_v2N_signature_hash_algorithms(c->sighash_policy, &rbody))
				return false;
		}
	} else {
		log_state(RC_LOG, &ike->sa,
			  "Impair: Skipping the Signature hash notify in IKE_SA_INIT Request");
	}

	/* Send NAT-T Notify payloads */
	if (!ikev2_out_nat_v2n(&rbody, &ike->sa, &zero_ike_spi/*responder unknown*/))
		return false;

	/* From here on, only payloads left are Vendor IDs */
	if (c->send_vendorid) {
		if (!emit_v2V(pluto_vendorid, &rbody))
			return false;
	}

	if (c->fake_strongswan) {
		if (!emit_v2V("strongSwan", &rbody))
			return false;
	}

	if (c->policy & POLICY_AUTH_NULL) {
		if (!emit_v2V("Opportunistic IPsec", &rbody))
			return STF_INTERNAL_ERROR;
	}

	close_output_pbs(&rbody);
	close_output_pbs(&reply_stream);

	/* save packet for later signing */
	replace_chunk(&ike->sa.st_firstpacket_me,
		      clone_pbs_out_as_chunk(&reply_stream, "saved first packet"));

	/* Transmit */
	record_v2_message(ike, &reply_stream, "IKE_SA_INIT request",
			  MESSAGE_REQUEST);
	return true;
}

/*
 *
 ***************************************************************
 *                       PARENT_INI1                       *****
 ***************************************************************
 *  -
 *
 *
 */

/* no state: none I1 --> R1
 *                <-- HDR, SAi1, KEi, Ni
 * HDR, SAr1, KEr, Nr, [CERTREQ] -->
 */

static ke_and_nonce_cb process_v2_IKE_SA_INIT_request_continue;	/* forward decl and type assertion */

stf_status process_v2_IKE_SA_INIT_request(struct ike_sa *ike,
					  struct child_sa *child,
					  struct msg_digest *md)
{
	pexpect(child == NULL);
	struct connection *c = ike->sa.st_connection;
	/* set up new state */
	update_ike_endpoints(ike, md);
	passert(ike->sa.st_ike_version == IKEv2);
	passert(ike->sa.st_state->kind == STATE_PARENT_R0);
	passert(ike->sa.st_sa_role == SA_RESPONDER);
	/* set by caller */
	pexpect(md->svm == finite_states[STATE_PARENT_R0]->v2_transitions);
	pexpect(md->svm->state == STATE_PARENT_R0);

	/* Vendor ID processing */
	for (struct payload_digest *v = md->chain[ISAKMP_NEXT_v2V]; v != NULL; v = v->next) {
		handle_vendorid(md, (char *)v->pbs.cur, pbs_left(&v->pbs), TRUE, ike->sa.st_logger);
	}

	/* Get the proposals ready. */
	struct ikev2_proposals *ike_proposals =
		get_v2_ike_proposals(c, "IKE SA responder matching remote proposals", ike->sa.st_logger);

	/*
	 * Select the proposal.
	 */
	stf_status ret = ikev2_process_sa_payload("IKE responder",
						  &md->chain[ISAKMP_NEXT_v2SA]->pbs,
						  /*expect_ike*/ TRUE,
						  /*expect_spi*/ FALSE,
						  /*expect_accepted*/ FALSE,
						  LIN(POLICY_OPPORTUNISTIC, c->policy),
						  &ike->sa.st_accepted_ike_proposal,
						  ike_proposals, ike->sa.st_logger);
	if (ret != STF_OK) {
		pexpect(ike->sa.st_sa_role == SA_RESPONDER);
		pexpect(ret > STF_FAIL);
		record_v2N_response(ike->sa.st_logger, ike, md,
				    ret - STF_FAIL, NULL,
				    UNENCRYPTED_PAYLOAD);
		return STF_FAIL;
	}

	if (DBGP(DBG_BASE)) {
		DBG_log_ikev2_proposal("accepted IKE proposal",
				       ike->sa.st_accepted_ike_proposal);
	}

	/*
	 * Convert what was accepted to internal form and apply some
	 * basic validation.  If this somehow fails (it shouldn't but
	 * ...), drop everything.
	 */
	if (!ikev2_proposal_to_trans_attrs(ike->sa.st_accepted_ike_proposal,
					   &ike->sa.st_oakley, ike->sa.st_logger)) {
		log_state(RC_LOG_SERIOUS, &ike->sa, "IKE responder accepted an unsupported algorithm");
		/* STF_INTERNAL_ERROR doesn't delete ST */
		return STF_FATAL;
	}

	/*
	 * Check the MODP group in the payload matches the accepted
	 * proposal.
	 */
	if (!v2_accept_ke_for_proposal(ike, &ike->sa, md,
				       ike->sa.st_oakley.ta_dh,
				       UNENCRYPTED_PAYLOAD)) {
		/* pexpect(reply-recorded) */
		return STF_FAIL;
	}

	/*
	 * Check and read the KE contents.
	 */
	/* note: v1 notification! */
	if (!unpack_KE(&ike->sa.st_gi, "Gi", ike->sa.st_oakley.ta_dh,
		       md->chain[ISAKMP_NEXT_v2KE], ike->sa.st_logger)) {
		send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL);
		return STF_FATAL;
	}

	/* extract results */
	ike->sa.st_seen_fragmentation_supported = md->pd[PD_v2N_IKEV2_FRAGMENTATION_SUPPORTED] != NULL;
	ike->sa.st_seen_ppk = md->pd[PD_v2N_USE_PPK] != NULL;
	ike->sa.st_seen_redirect_sup = (md->pd[PD_v2N_REDIRECTED_FROM] != NULL ||
					md->pd[PD_v2N_REDIRECT_SUPPORTED] != NULL);

	/*
	 * Responder: check v2N_NAT_DETECTION_DESTINATION_IP or/and
	 * v2N_NAT_DETECTION_SOURCE_IP.
	 *
	 *   2.23.  NAT Traversal
	 *
	 *   The IKE initiator MUST check the NAT_DETECTION_SOURCE_IP
	 *   or NAT_DETECTION_DESTINATION_IP payloads if present, and
	 *   if they do not match the addresses in the outer packet,
	 *   MUST tunnel all future IKE and ESP packets associated
	 *   with this IKE SA over UDP port 4500.
	 *
	 * Since this is the responder, there's really not much to do.
	 * It is the initiator that will switch to port 4500 (float
	 * away) when necessary.
	 */
	if (v2_nat_detected(ike, md)) {
		dbg("NAT: responder so initiator gets to switch ports");
		/* should this check that a port is available? */
	}

	if (md->pd[PD_v2N_SIGNATURE_HASH_ALGORITHMS] != NULL) {
		if (impair.ignore_hash_notify_response) {
			log_state(RC_LOG, &ike->sa, "IMPAIR: ignoring the hash notify in IKE_SA_INIT request");
		} else if (!negotiate_hash_algo_from_notification(&md->pd[PD_v2N_SIGNATURE_HASH_ALGORITHMS]->pbs, ike)) {
			return STF_FATAL;
		}
		ike->sa.st_seen_hashnotify = true;
	}

	/* calculate the nonce and the KE */
	submit_ke_and_nonce(&ike->sa,
			    ike->sa.st_oakley.ta_dh,
			    process_v2_IKE_SA_INIT_request_continue,
			    "process_v2_IKE_SA_INIT_request_continue");
	return STF_SUSPEND;
}

static stf_status process_v2_IKE_SA_INIT_request_continue(struct state *ike_st,
							  struct msg_digest *md,
							  struct dh_local_secret *local_secret,
							  chunk_t *nonce)
{
	struct ike_sa *ike = pexpect_ike_sa(ike_st);
	pexpect(ike->sa.st_sa_role == SA_RESPONDER);
	pexpect(v2_msg_role(md) == MESSAGE_REQUEST); /* i.e., MD!=NULL */
	pexpect(ike->sa.st_state->kind == STATE_PARENT_R0);
	dbg("%s() for #%lu %s: calculated ke+nonce, sending R1",
	    __func__, ike->sa.st_serialno, ike->sa.st_state->name);

	struct connection *c = ike->sa.st_connection;
	bool send_certreq = FALSE;

	/* note that we don't update the state here yet */

	/*
	 * XXX:
	 *
	 * Should this code use clone_in_pbs_as_chunk() which uses
	 * pbs_room() (.roof-.start)?  The original code:
	 *
	 * 	clonetochunk(ike->sa.st_firstpacket_peer, md->message_pbs.start,
	 *		     pbs_offset(&md->message_pbs),
	 *		     "saved first received packet");
	 *
	 * and clone_out_pbs_as_chunk() both use pbs_offset()
	 * (.cur-.start).
	 *
	 * Suspect it doesn't matter as the code initializing
	 * .message_pbs forces .roof==.cur - look for the comment
	 * "trim padding (not actually legit)".
	 */
	/* record first packet for later checking of signature */
	replace_chunk(&ike->sa.st_firstpacket_peer,
		      clone_pbs_out_as_chunk(&md->message_pbs,
			"saved first received packet in inI1outR1_continue_tail"));

	/* make sure HDR is at start of a clean buffer */
	struct pbs_out reply_stream = open_pbs_out("reply packet",
						   reply_buffer, sizeof(reply_buffer),
						   ike->sa.st_logger);

	/* HDR out */
	struct pbs_out rbody = open_v2_message(&reply_stream, ike,
					       md /* response */,
					       ISAKMP_v2_IKE_SA_INIT);
	if (!pbs_ok(&rbody)) {
		return STF_INTERNAL_ERROR;
	}

	/* start of SA out */
	{
		/*
		 * Since this is the initial IKE exchange, the SPI is
		 * emitted as part of the packet header and not as
		 * part of the proposal.  Hence the NULL SPI.
		 */
		passert(ike->sa.st_accepted_ike_proposal != NULL);
		if (!ikev2_emit_sa_proposal(&rbody, ike->sa.st_accepted_ike_proposal, NULL)) {
			dbg("problem emitting accepted proposal");
			return STF_INTERNAL_ERROR;
		}
	}

	/* Ni in */
	if (!accept_v2_nonce(ike->sa.st_logger, md, &ike->sa.st_ni, "Ni")) {
		/*
		 * Presumably not our fault.  Syntax errors kill the
		 * family, hence FATAL.
		 */
		record_v2N_response(ike->sa.st_logger, ike, md,
				    v2N_INVALID_SYNTAX, NULL/*no-data*/,
				    UNENCRYPTED_PAYLOAD);
		return STF_FATAL;
	}

	/* ??? from here on, this looks a lot like the end of ikev2_parent_outI1_common */

	/*
	 * Unpack and send KE
	 *
	 * Pass the crypto helper's oakley group so that it is
	 * consistent with what was unpacked.
	 *
	 * IKEv2 code (arguably, incorrectly) uses st_oakley.ta_dh to
	 * track the most recent KE sent out.  It should instead be
	 * maintaining a list of KEs sent out (so that they can be
	 * reused should the initial responder flip-flop) and only set
	 * st_oakley.ta_dh once the proposal has been accepted.
	 */
	pexpect(ike->sa.st_oakley.ta_dh == dh_local_secret_desc(local_secret));
	unpack_KE_from_helper(&ike->sa, local_secret, &ike->sa.st_gr);
	if (!emit_v2KE(&ike->sa.st_gr, dh_local_secret_desc(local_secret), &rbody)) {
		return STF_INTERNAL_ERROR;
	}

	/* send NONCE */
	unpack_nonce(&ike->sa.st_nr, nonce);
	{
		pb_stream pb;
		struct ikev2_generic in = {
			.isag_critical = build_ikev2_critical(false, ike->sa.st_logger),
		};

		if (!out_struct(&in, &ikev2_nonce_desc, &rbody, &pb) ||
		    !out_hunk(ike->sa.st_nr, &pb, "IKEv2 nonce"))
			return STF_INTERNAL_ERROR;

		close_output_pbs(&pb);
	}

	/* decide to send a CERTREQ - for RSASIG or GSSAPI */
	send_certreq = (((c->policy & POLICY_RSASIG) &&
			 !has_preloaded_public_key(&ike->sa)));

	/* Send fragmentation support notification */
	if (c->policy & POLICY_IKE_FRAG_ALLOW) {
		if (!emit_v2N(v2N_IKEV2_FRAGMENTATION_SUPPORTED, &rbody))
			return STF_INTERNAL_ERROR;
	}

	/* Send USE_PPK Notify payload */
	if (ike->sa.st_seen_ppk) {
		if (!emit_v2N(v2N_USE_PPK, &rbody))
			return STF_INTERNAL_ERROR;
	 }

	/* Send INTERMEDIATE_EXCHANGE_SUPPORTED Notify payload */
	if ((c->policy & POLICY_INTERMEDIATE) &&
	    md->pd[PD_v2N_INTERMEDIATE_EXCHANGE_SUPPORTED] != NULL) {
		if (!emit_v2N(v2N_INTERMEDIATE_EXCHANGE_SUPPORTED, &rbody))
			return STF_INTERNAL_ERROR;
		ike->sa.st_v2_ike_intermediate_used = true;
	}

	/* Send SIGNATURE_HASH_ALGORITHMS notification only if we received one */
	if (!impair.ignore_hash_notify_request) {
		if (ike->sa.st_seen_hashnotify && ((c->policy & POLICY_RSASIG) || (c->policy & POLICY_ECDSA))
			&& (c->sighash_policy != LEMPTY)) {
			if (!emit_v2N_signature_hash_algorithms(c->sighash_policy, &rbody))
				return STF_INTERNAL_ERROR;
		}
	} else {
		log_state(RC_LOG, &ike->sa, "Impair: Not sending out signature hash notify");
	}

	/* Send NAT-T Notify payloads */
	if (!ikev2_out_nat_v2n(&rbody, &ike->sa, &ike->sa.st_ike_spis.responder)) {
		return STF_INTERNAL_ERROR;
	}

	/* something the other end won't like */

	/* send CERTREQ */
	if (send_certreq) {
		dbg("going to send a certreq");
		ikev2_send_certreq(&ike->sa, md, &rbody);
	}

	if (c->send_vendorid) {
		if (!emit_v2V(pluto_vendorid, &rbody))
			return STF_INTERNAL_ERROR;
	}

	if (c->fake_strongswan) {
		if (!emit_v2V("strongSwan", &rbody))
			return STF_INTERNAL_ERROR;
	}

	if (c->policy & POLICY_AUTH_NULL) {
		if (!emit_v2V("Opportunistic IPsec", &rbody))
			return STF_INTERNAL_ERROR;
	}

	close_output_pbs(&rbody);
	close_output_pbs(&reply_stream);

	record_v2_message(ike, &reply_stream,
			  "reply packet for IKE_SA_INIT request",
			  MESSAGE_RESPONSE);

	/* save packet for later signing */
	replace_chunk(&ike->sa.st_firstpacket_me,
		      clone_pbs_out_as_chunk(&reply_stream, "saved first packet"));

	return STF_OK;
}

/*
 *
 ***************************************************************
 *                       PARENT_inR1                       *****
 ***************************************************************
 *  -
 *
 *
 */
/* STATE_PARENT_I1: R1B --> I1B
 *                     <--  HDR, N
 * HDR, N(COOKIE), SAi1, KEi, Ni -->
 */

static stf_status resubmit_ke_and_nonce(struct ike_sa *ike)
{
	submit_ke_and_nonce(&ike->sa, ike->sa.st_oakley.ta_dh,
			    ikev2_parent_outI1_continue,
			    "rekey outI");
	return STF_SUSPEND;
}

stf_status process_v2_IKE_SA_INIT_response_v2N_INVALID_KE_PAYLOAD(struct ike_sa *ike,
								  struct child_sa *child,
								  struct msg_digest *md)
{
	struct connection *c = ike->sa.st_connection;

	pexpect(child == NULL);
	if (!pexpect(md->pd[PD_v2N_INVALID_KE_PAYLOAD] != NULL)) {
		return STF_INTERNAL_ERROR;
	}
	struct pbs_in invalid_ke_pbs = md->pd[PD_v2N_INVALID_KE_PAYLOAD]->pbs;

	/* careful of DDOS, only log with debugging on? */
	/* we treat this as a "retransmit" event to rate limit these */
	if (!count_duplicate(&ike->sa, MAXIMUM_INVALID_KE_RETRANS)) {
		dbg("ignoring received INVALID_KE packets - received too many (DoS?)");
		return STF_IGNORE;
	}

	/*
	 * There's at least this notify payload, is there more than
	 * one?
	 */
	if (md->chain[ISAKMP_NEXT_v2N]->next != NULL) {
		dbg("ignoring other notify payloads");
	}

	struct suggested_group sg;
	diag_t d = pbs_in_struct(&invalid_ke_pbs, &suggested_group_desc,
				 &sg, sizeof(sg), NULL);
	if (d != NULL) {
		llog_diag(RC_LOG, ike->sa.st_logger, &d, "%s", "");
		return STF_IGNORE;
	}

	pstats(invalidke_recv_s, sg.sg_group);
	pstats(invalidke_recv_u, ike->sa.st_oakley.ta_dh->group);

	struct ikev2_proposals *ike_proposals =
		get_v2_ike_proposals(c, "IKE SA initiator validating remote's suggested KE", ike->sa.st_logger);
	if (!ikev2_proposals_include_modp(ike_proposals, sg.sg_group)) {
		esb_buf esb;
		log_state(RC_LOG, &ike->sa,
			  "Discarding unauthenticated INVALID_KE_PAYLOAD response to DH %s; suggested DH %s is not acceptable",
			  ike->sa.st_oakley.ta_dh->common.fqn,
			  enum_show_short(&oakley_group_names,
					  sg.sg_group, &esb));
		return STF_IGNORE;
	}

	dbg("Suggested modp group is acceptable");
	/*
	 * Since there must be a group object for every local
	 * proposal, and sg.sg_group matches one of the local proposal
	 * groups, a lookup of sg.sg_group must succeed.
	 */
	const struct dh_desc *new_group = ikev2_get_dh_desc(sg.sg_group);
	passert(new_group != NULL);
	log_state(RC_LOG, &ike->sa,
		  "Received unauthenticated INVALID_KE_PAYLOAD response to DH %s; resending with suggested DH %s",
		  ike->sa.st_oakley.ta_dh->common.fqn,
		  new_group->common.fqn);
	ike->sa.st_oakley.ta_dh = new_group;
	/* wipe our mismatched KE */
	dh_local_secret_delref(&ike->sa.st_dh_local_secret, HERE);
	/*
	 * get a new KE
	 */
	schedule_reinitiate_v2_ike_sa_init(ike, resubmit_ke_and_nonce);
	return STF_OK;
}

/* STATE_PARENT_I1: R1 --> I2
 *                     <--  HDR, SAr1, KEr, Nr, [CERTREQ]
 * HDR, SK {IDi, [CERT,] [CERTREQ,]
 *      [IDr,] AUTH, SAi2,
 *      TSi, TSr}      -->
 */

/*
 * XXX: there's a lot of code duplication between the IKE_AUTH and
 * IKE_INTERMEDIATE paths.
 */

stf_status process_v2_IKE_SA_INIT_response(struct ike_sa *ike,
					   struct child_sa *unused_child UNUSED,
					   struct msg_digest *md)
{
	struct connection *c = ike->sa.st_connection;

	/* for testing only */
	if (impair.send_no_ikev2_auth) {
		log_state(RC_LOG, &ike->sa,
			  "IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet");
		return STF_IGNORE;
	}

	/*
	 * if this connection has a newer Child SA than this state
	 * this negotiation is not relevant any more.  would this
	 * cover if there are multiple CREATE_CHILD_SA pending on this
	 * IKE negotiation ???
	 *
	 * XXX: this is testing for an IKE SA that's been superseed by
	 * a newer IKE SA (not child).  Suspect this is to handle a
	 * race where the other end brings up the IKE SA first?  For
	 * that case, shouldn't this state have been deleted?
	 *
	 * NOTE: a larger serialno does not mean superseded. crossed
	 * streams could mean the lower serial established later and is
	 * the "newest". Should > be replaced with !=   ?
	 */
	if (c->newest_ipsec_sa > ike->sa.st_serialno) {
		log_state(RC_LOG, &ike->sa,
			  "state superseded by #%lu try=%lu, drop this negotiation",
			  c->newest_ipsec_sa, ike->sa.st_try);
		return STF_FATAL;
	}

	/*
	 * XXX: this iteration over the notifies modifies state
	 * _before_ the code's committed to creating an SA.  Hack this
	 * by resetting any flags that might be set.
	 */
	ike->sa.st_seen_fragmentation_supported = false;
	ike->sa.st_seen_ppk = false;

	ike->sa.st_seen_fragmentation_supported = md->pd[PD_v2N_IKEV2_FRAGMENTATION_SUPPORTED] != NULL;
	ike->sa.st_seen_ppk = md->pd[PD_v2N_USE_PPK] != NULL;
	if (md->pd[PD_v2N_SIGNATURE_HASH_ALGORITHMS] != NULL) {
		if (impair.ignore_hash_notify_request) {
			log_state(RC_LOG, &ike->sa,
				  "IMPAIR: ignoring the Signature hash notify in IKE_SA_INIT response");
		} else if (!negotiate_hash_algo_from_notification(&md->pd[PD_v2N_SIGNATURE_HASH_ALGORITHMS]->pbs, ike)) {
			return STF_FATAL;
		}
		ike->sa.st_seen_hashnotify = true;
	}

	/*
	 * the responder sent us back KE, Gr, Nr, and it's our time to calculate
	 * the shared key values.
	 */

	dbg("ikev2 parent inR1: calculating g^{xy} in order to send I2");

	/* KE in */
	if (!unpack_KE(&ike->sa.st_gr, "Gr", ike->sa.st_oakley.ta_dh,
		       md->chain[ISAKMP_NEXT_v2KE], ike->sa.st_logger)) {
		/*
		 * XXX: Initiator - so this code will not trigger a
		 * notify.  Since packet isn't trusted, should it be
		 * ignored?
		 */
		return STF_FAIL + v2N_INVALID_SYNTAX;
	}

	/* Ni in */
	if (!accept_v2_nonce(ike->sa.st_logger, md, &ike->sa.st_nr, "Nr")) {
		/*
		 * Presumably not our fault.  Syntax errors in a
		 * response kill the family (and trigger no further
		 * exchange).
		 */
		return STF_FATAL;
	}

	/* We're missing processing a CERTREQ in here */

	/* process and confirm the SA selected */
	{
		/* SA body in and out */
		struct payload_digest *const sa_pd =
			md->chain[ISAKMP_NEXT_v2SA];
		struct ikev2_proposals *ike_proposals =
			get_v2_ike_proposals(c, "IKE SA initiator accepting remote proposal", ike->sa.st_logger);

		stf_status ret = ikev2_process_sa_payload("IKE initiator (accepting)",
							  &sa_pd->pbs,
							  /*expect_ike*/ TRUE,
							  /*expect_spi*/ FALSE,
							  /*expect_accepted*/ TRUE,
							  LIN(POLICY_OPPORTUNISTIC, c->policy),
							  &ike->sa.st_accepted_ike_proposal,
							  ike_proposals, ike->sa.st_logger);
		if (ret != STF_OK) {
			dbg("ikev2_parse_parent_sa_body() failed in ikev2_parent_inR1outI2()");
			return ret; /* initiator; no response */
		}

		if (!ikev2_proposal_to_trans_attrs(ike->sa.st_accepted_ike_proposal,
						   &ike->sa.st_oakley, ike->sa.st_logger)) {
			log_state(RC_LOG_SERIOUS, &ike->sa,
				  "IKE initiator proposed an unsupported algorithm");
			free_ikev2_proposal(&ike->sa.st_accepted_ike_proposal);
			passert(ike->sa.st_accepted_ike_proposal == NULL);
			/*
			 * Assume caller et.al. will clean up the
			 * reset of the mess?
			 */
			return STF_FAIL;
		}
	}
	replace_chunk(&ike->sa.st_firstpacket_peer,
		      clone_pbs_out_as_chunk(&md->message_pbs,
					     "saved first received packet in inR1outI2"));

	/*
	 * Initiator: check v2N_NAT_DETECTION_DESTINATION_IP or/and
	 * v2N_NAT_DETECTION_SOURCE_IP.
	 *
	 *   2.23.  NAT Traversal
	 *
	 *   The IKE initiator MUST check the NAT_DETECTION_SOURCE_IP
	 *   or NAT_DETECTION_DESTINATION_IP payloads if present, and
	 *   if they do not match the addresses in the outer packet,
	 *   MUST tunnel all future IKE and ESP packets associated
	 *   with this IKE SA over UDP port 4500.
	 *
	 * When detected, float to the NAT port as needed (*ikeport
	 * can't float but already supports NAT).  When the ports
	 * can't support NAT, give up.
	 */

	if (v2_nat_detected(ike, md)) {
		pexpect(ike->sa.hidden_variables.st_nat_traversal & NAT_T_DETECTED);
		if (!v2_natify_initiator_endpoints(ike, HERE)) {
			/* already logged */
			return STF_FATAL;
		}
	}

	/*
	 * Initiate the calculation of g^xy.
	 *
	 * Form and pass in the full SPI[ir] that will eventually be
	 * used by this IKE SA.  Only once DH has been computed and
	 * the SA is secure (but not authenticated) should the state's
	 * IKE SPIr be updated.
	 */

	pexpect(ike_spi_is_zero(&ike->sa.st_ike_spis.responder));
	ike->sa.st_ike_rekey_spis = (ike_spis_t) {
		.initiator = ike->sa.st_ike_spis.initiator,
		.responder = md->hdr.isa_ike_responder_spi,
	};

	/*
	 * If we seen the intermediate AND we are configured to use
	 * intermediate.
	 *
	 * For now, do only one Intermediate Exchange round and
	 * proceed with IKE_AUTH.
	 */
	ike->sa.st_v2_ike_intermediate_used = ((c->policy & POLICY_INTERMEDIATE) &&
					       md->pd[PD_v2N_INTERMEDIATE_EXCHANGE_SUPPORTED] != NULL);

	dh_shared_secret_cb (*pcrc_func) =
		(ike->sa.st_v2_ike_intermediate_used /* SHH: GNU style ?: */
		 ? ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_INTERMEDIATE_I_continue
		 : ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_continue);

	submit_dh_shared_secret(&ike->sa, ike->sa.st_gr/*initiator needs responder KE*/,
				pcrc_func, HERE);
	return STF_SUSPEND;
}
